/**
 * 
 */
package anyware.common.dao.support;

import java.io.Serializable;
import java.util.Collection;

import javax.annotation.Resource;

import org.apache.commons.lang.Validate;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Example;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import anyware.common.dao.GenericDao;

/**
 * @author keke
 * 
 */
public class HibernateGenericDaoSupport<E, ID extends Serializable> extends
        HibernateDaoSupport implements GenericDao<E, ID, Criteria> {

    protected Class<E> clazz;

    public HibernateGenericDaoSupport(final Class<E> clazz) {
        super();
        this.clazz = clazz;
    }

    public GenericDao<E, ID, Criteria> delete(final E entity) {
        Validate.notNull(entity);
        currentSession().delete(entity);
        return this;
    }

    public Collection<E> find(final Criteria queryCriteria) {
        return queryCriteria.list();
    }

    public Collection<E> findByExample(final E example) {
        return currentSession().createCriteria(clazz).add(
                Example.create(example)).list();
    }

    public E findOneByExample(final E example) {
        return (E) currentSession().createCriteria(clazz).add(
                Example.create(example)).setMaxResults(1).uniqueResult();
    }

    public E findOnly(final Criteria queryCriteria) {
        return (E) queryCriteria.setMaxResults(1).uniqueResult();
    }

    public E get(final ID id) {
        Validate.notNull(id);
        return (E) currentSession().get(clazz, id);
    }

    @Deprecated
    public Collection<E> getByExample(final E e) {
        return findByExample(e);

    }

    @Deprecated
    public E getOnlyByExample(final E e) {
        return findOneByExample(e);

    }

    public Collection<E> listAll() {
        return currentSession().createCriteria(clazz).list();
    }

    public GenericDao<E, ID, Criteria> save(final E entity) {
        currentSession().saveOrUpdate(entity);
        return this;
    }

    @Resource
    public void setSessionFactoryAuto(final SessionFactory sessionFactory) {
        setSessionFactory(sessionFactory);
    }

    protected Session currentSession() {
        return getSessionFactory().getCurrentSession();
    }

}
